#include <cstdio>
#include <cstring>
#include "utils/sorted_search.hxx"
#include "utils/scan.hxx"
#include "utils/utils.hxx"
#include "utils/platform.hxx"

void init_data(int *buf, int len, int range){
  for(int i=0; i<len; i++){
    buf[i] = rand()%range;
  }
}

int scan_data(int *input, int* &output, int len){
  int *din, *dsum;
  int retval;
  H_ERR(hipMalloc(&output, sizeof(int)*len));
  H_ERR(hipMalloc(&din, sizeof(int)*len));
  H_ERR(hipMalloc(&dsum, sizeof(int)));
  TODEV(din, input, len);
  double s=mwtime();
  scan(din, output, len, dsum);
  CUBARRIER();
  double e=mwtime(); printf("%f\n", e-s);
  TOHOST(dsum, &retval, 1);
  return retval;
}

int main(int argc, char* argv[]){
  int ksz = atoi(argv[1]);
  int vsz = atoi(argv[2]);
  int *value = new int[vsz];
  int *key = new int[ksz];
  int *dk, *dv, *didx;

  init_data(value, vsz, 64);
  int range = scan_data(value, dv, vsz);
  init_data(key, ksz, range/ksz);
  scan_data(key, dk, ksz);
  H_ERR(hipMalloc(&didx, sizeof(int)*ksz));
  //dump_arr(dk, ksz);
  //dump_arr(dv, vsz);

  int *shit;
  hipMalloc(&shit, sizeof(int)*2);
  hipMemset(shit, 0, sizeof(int)*2);
  auto f = block_sort<int,128,32>;
  hipLaunchKernelGGL(f, dim3(1), dim3(1), 0, 0, dk, 1, dv, 1, shit, didx);
  CUBARRIER();

  hipMemset(didx, 0, sizeof(int)*ksz);
  //double s=mwtime();
  sorted_search1(dk, ksz, dv, vsz, didx);
  CUBARRIER();
  //double e=mwtime(); printf("%f", e-s);
  //dump_arr(didx, ksz);
  hipFree(didx);
  hipFree(dk);
  hipFree(dv);
  delete[] value;
  delete[] key;
  return 0;
}
